﻿namespace DataIntegration.Triggers
{
    using System;
    using System.Threading;
    using Entities;
    using Entities.Triggers;
    using Messaging.Publisher;
    using Utils;
    using Utils.Lifecycle.Base;
    using Utils.Serialization;

    public abstract class Trigger : BaseLifecycle, IBrokerComponent
    {
        protected abstract void StartTrigger();

        protected abstract void DisposeTrigger();

        private event Action<TriggerInstruction> Fire;

        private readonly string name;

        private readonly IPublisherFactory publisherFactory;

        private IPublisher publisher;

        private string daemonName;
        
        protected Trigger(string name, IPublisherFactory publisherFactory)
        {
            this.name = name;
            this.publisherFactory = publisherFactory;
        }

        public string DaemonName
        {
            set { this.daemonName = value; }
        }

        public override void Dispose()
        {
            this.DisposeTrigger();
        }

        protected void InvokeFire(TriggerInstruction triggerInstruction)
        {
            Action<TriggerInstruction> action = this.Fire;

            if (action != null)
            {
                ThreadPool.QueueUserWorkItem(delegate { action(triggerInstruction); });
            }
        }

        protected override void Setup()
        {
            this.Fire += this.Publish;
            this.publisher = this.publisherFactory.GetPublisher(this.daemonName, MessageType.Trigger, this.name);
            this.publisher.Start();
            this.StartTrigger();
        }

        private void Publish(TriggerInstruction triggerInstruction)
        {
            string xml = SerializationFactory.SerializeToXmlString(triggerInstruction);
            string topic = string.Format("{0}.{1}.{2}", App.Name, MessageType.Trigger, this.name);
            Guid guid = Guid.NewGuid();
            this.publisher.Publish(topic, guid.ToString(), xml);
        }
    }
}
